package ywq;

import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;


public class DrawDraw extends JFrame {
    public static void main(String[] args) {
        new DrawDraw();
    }

    // 属性 初始化
    JPanel toolsPanel, canvasPanel, controlPanel;

    // 按钮 插入图片 和裁剪
    private JButton insertImageButton;
    private JButton clipButton;
    private JSlider slider;
    // 当前的颜色
    Color currentColor;

    float strokeWidth = 1.0f;
    // 当前选择的图形
    String shape = Shape.CURVE.getName();
    int startX, startY;
    Graphics2D g;
    BufferedImage originalImage;
    JButton colorButton;
    private Rectangle clipArea;
    private boolean isClip = false;

    private int  preWidth;
    private int preHeight;
    private int preX;
    private int preY;

    DrawDraw() {

        toolsPanel = new JPanel();
        canvasPanel = new JPanel();


        setTitle("画画面板");
        this.setSize(1400, 900);
        this.setLocation(100, 100);
        slider = new JSlider(JSlider.HORIZONTAL, 1, 10, 2); // 范围从1到10，初始值为2
        slider.setPaintLabels(true); // 显示标签
        slider.setMajorTickSpacing(2); // 主刻度间隔
        slider.setPaintTicks(true); // 显示刻度

        slider.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                int value = slider.getValue();
                strokeWidth = value * 0.5f; // 将滑块值映射到合适的画笔粗细
            }
        });


        controlPanel = new JPanel(new FlowLayout());
        controlPanel.add(new JLabel("画笔粗细"));
        controlPanel.add(slider);

        // 颜色选择器
        colorButton = new JButton("颜色选择");
        colorButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Color newColor = JColorChooser.showDialog(null, "Choose a color", currentColor);
                if (newColor != null) {
                    currentColor = newColor;
                }
            }
        });

        insertImageButton = new JButton("插入图片");
        insertImageButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileChooser = new JFileChooser();
                FileNameExtensionFilter filter = new FileNameExtensionFilter("Image files", "jpg", "jpeg", "png", "gif");
                fileChooser.setFileFilter(filter);
                int returnValue = fileChooser.showOpenDialog(null);
                if (returnValue == JFileChooser.APPROVE_OPTION) {
                    File selectedFile = fileChooser.getSelectedFile();
                    try {
                        originalImage = ImageIO.read(selectedFile);
                        Graphics g = canvasPanel.getGraphics();
                        g.drawImage(originalImage, 0, 0, null);

                        // originalImage
                          preWidth = originalImage.getWidth();
                          preHeight = originalImage.getHeight();
                        preX=0;
                        preY=0;
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });

        clipButton = new JButton("裁剪");
        clipButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
//                clipArea = getClipArea();

                shape = Shape.RECTANGLE.getName();
                isClip = true;
            }
        });


        toolsPanel.add(colorButton);
        toolsPanel.add(insertImageButton);
        toolsPanel.add(clipButton);


        Shape[] values = Shape.values();
        // 图形按钮，采用数组的方式添加按钮。好处在更改代码的时候，可以直接添加，十分方便
//        String[] Shape = {"直线", "曲线", "圆", "喷枪", "橡皮擦", "矩形", "椭圆", "圆角矩形", "弧线"};

        for (int i = 0; i < values.length; i++) {
            JButton button = new JButton(values[i].getName());
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JButton button = (JButton) e.getSource();
                    shape = button.getActionCommand();
                    System.out.println("String = " + shape);
                }
            });  //添加事件监听机制 类(this)应该是有实现了ActionListener这个接口的吧;
            toolsPanel.add(button);
        }


        // 设置背景颜色
        toolsPanel.setBackground(Color.gray);
//        canvasPanel.setBackground(Color.white);


        // 把p0,p1,p2 上-中-下的方法分配
        this.add(toolsPanel, BorderLayout.NORTH);
        this.add(canvasPanel, BorderLayout.CENTER);
        this.add(controlPanel, BorderLayout.SOUTH);


        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        // 注意：这里鼠标移动和鼠标拖动的事件，是作用在p1的面板上面。。。类(this)应该是有实现了MouseListener,MouseMotionListener
        canvasPanel.addMouseListener(new MouseAdapter() {
            /**
             * {@inheritDoc}
             *
             * @param e
             */
            @Override
            public void mousePressed(MouseEvent e) {
                super.mousePressed(e);
                g = (Graphics2D) canvasPanel.getGraphics(); // g = p1.getGraphics();
                g.setColor(currentColor);
                g.setStroke(new BasicStroke(strokeWidth));
                // 鼠标点击下的位置 就是开始位置
                startX = e.getX(); // 返回事件相对于源组件的水平x位置。
                startY = e.getY();

            }

            @Override
            public void mouseReleased(MouseEvent e) {
                g.setColor(currentColor);
                int endX = e.getX();
                int endY = e.getY();
                Shape shape = Shape.getByValue(DrawDraw.this.shape);
                switch (shape) {
                    case LINE:
                        g.drawLine(startX, startY, endX, endY);
                        break;
                    case RECTANGLE:
                        // 处理矩形的大小和方向问题 画笔的绘制方向
                        if (startX > endX) {
                            int temp = startX;
                            startX = endX;
                            endX = temp;
                        }
                        if (startY > endY) {
                            int temp = startY;
                            startY = endY;
                            endY = temp;
                        }

                        if (isClip) {
                            clipArea = new Rectangle(startX, startY, Math.abs(endX - startX), Math.abs(endY - startY));
                            if (clipArea != null) {

                                // 清除上一次的图片
                                g.clearRect(preX, preY,preWidth, preHeight);
                                BufferedImage croppedImage = cropImage(originalImage, clipArea);
                                g.drawImage(croppedImage, startX, startY, null);
                                preX =startX;
                                preY =startY;
                                preWidth = croppedImage.getWidth();
                                preHeight = croppedImage.getHeight();
                            }
                            isClip = false;
                        } else {
                            g.drawRect(startX, startY, Math.abs(endX - startX), Math.abs(endY - startY));
                        }
                        break;
                    case ROUNDRECTANGLE:
                        if (startX > endX) {
                            int temp = startX;
                            startX = endX;
                            endX = temp;
                        }
                        if (startY > endY) {
                            int temp = startY;
                            startY = endY;
                            endY = temp;
                        }
                        g.drawRoundRect(startX, startY, Math.abs(endX - startX), Math.abs(endY - startY), 5, 10);
                        break;
                    case ELLIPSE:
                        if (startX > endX) {
                            int temp = startX;
                            startX = endX;
                            endX = temp;
                        }
                        if (startY > endY) {
                            int temp = startY;
                            startY = endY;
                            endY = temp;
                        }
                        g.drawOval(startX, startY, Math.abs(endX - startX), Math.abs(endY - startY));
                        break;

                    case CIRCLE:
                        if (startX > endX) {
                            int temp = startX;
                            startX = endX;
                            endX = temp;
                        }
                        if (startY > endY) {
                            int temp = startY;
                            startY = endY;
                            endY = temp;
                        }
                        g.drawOval(startX, startY, Math.abs(endX - startX), Math.abs(endY - startY));


                        break;
                    default:
                        break;

                }


            }
        });
        canvasPanel.addMouseMotionListener(new MouseMotionListener() {
            @Override
            public void mouseDragged(MouseEvent e) {
                int endX = e.getX();
                int endY = e.getY();
                if (shape.equals(Shape.CURVE.getName())) {
                    g.drawLine(startX, startY, endX, endY);
                    startX = endX;
                    startY = endY;
                } else if (shape.equals(Shape.ERASER.getName())) {
                    // Graphics2D中的方法。BasicStroke(float width)--->指的是宽度
                    g.setStroke(new BasicStroke(80));
                    // 好像是渲染，应该就是给涂掉
                    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                    g.setColor(Color.WHITE);
                    g.drawLine(startX, startY, endX, endY);
                    startX = endX;
                    startY = endY;
                } else if (shape.equals(Shape.PEN.getName())) {
                    // 循环控制颗粒度
                    for (int k = 0; k < 50; k++) {
                        Random i = new Random();
                        int a = i.nextInt(8);
                        int b = i.nextInt(10);
                        g.drawLine(endX + a, endY + b, endX + a, endY + b);
                    }
                }
            }

            @Override
            public void mouseMoved(MouseEvent e) {

            }

        });

    }

    // 裁剪图片的方法
    private BufferedImage cropImage(BufferedImage src, Rectangle clipArea) {
        return src.getSubimage(clipArea.x, clipArea.y, clipArea.width, clipArea.height);
    }


}

 